package management

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/bitly/go-simplejson"
	"github.com/gorilla/mux"
	"github.com/jsrccb/nachuan/common"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type RoleMgr struct {
	client               *mongo.Client
	roleCollection       *mongo.Collection
	roleLimitsCollection *mongo.Collection
	departCollection     *mongo.Collection
}

var (
	G_roleMgr *RoleMgr
)

func (roleMgr *RoleMgr) updSaveRoleLimitsInfo(roleLimits *common.RoleLimits) (err error) {

	var (
		// resultOne *mongo.InsertOneResult
		doccount   int64
		roleFilter *common.RoleFilter
		// update *common.HostInfo
	)
	roleLimits.CreateTime = common.BuildTimeNowStr()

	roleFilter = &common.RoleFilter{
		RoleName: roleLimits.RoleName,
		PartName: roleLimits.PartName,
		PartOpt:  roleLimits.PartOpt,
	}

	if doccount, err = roleMgr.roleLimitsCollection.CountDocuments(context.TODO(), roleFilter); err != nil {
		fmt.Println(err.Error())
		return
	}

	if doccount > 0 {
		roleMgr.roleLimitsCollection.FindOneAndUpdate(context.TODO(), roleFilter, bson.M{"$set": roleLimits})
	} else {
		roleMgr.roleLimitsCollection.InsertOne(context.TODO(), roleLimits)
	}

	return
}

func (roleMgr *RoleMgr) deleteRoleLimitsInfo(rolename string) (err error) {

	var (
		// resultOne *mongo.InsertOneResult
		// partFilter *common.PartFilter
		// findopt  *options.FindOption
		ctx        context.Context
		roleFilter *common.RoleByNameFilter
		// update *common.HostInfo
	)
	roleFilter = &common.RoleByNameFilter{
		RoleName: rolename,
	}

	if _, err = roleMgr.roleLimitsCollection.DeleteMany(ctx, roleFilter, &options.DeleteOptions{}); err != nil {

		// fmt.Println(err.Error)
		return
	}
	return
}

func (roleMgr *RoleMgr) queryRoleLimitsInfo(rolename string) (roleinfoarr []*common.RoleLimits, err error) {

	var (
		cursor *mongo.Cursor
		// findopt  *options.FindOption
		ctx        context.Context
		rolelimits *common.RoleLimits
		roleFilter *common.RoleByNameFilter
		// update *common.HostInfo
	)
	roleFilter = &common.RoleByNameFilter{
		RoleName: rolename,
	}

	// fmt.Println(roleFilter)

	if cursor, err = roleMgr.roleLimitsCollection.Find(ctx, roleFilter, &options.FindOptions{}); err != nil {

		// fmt.Println(err.Error)
		return
	}

	defer cursor.Close(ctx)

	for cursor.Next(ctx) {
		rolelimits = &common.RoleLimits{}
		if err = cursor.Decode(rolelimits); err != nil {
			continue
		}
		roleinfoarr = append(roleinfoarr, rolelimits)
	}

	return
}

func initRoleLimitsApi(r *mux.Router) {
	s := r.PathPrefix("/rolelimits").Subrouter()
	// s.HandleFunc("/list", UserListHandler)
	s.HandleFunc("/updsave", handleOpdSaveRoleInfo)
	//请求/rolelimits/querybyrolename?rolename=xxx
	s.HandleFunc("/querybyrolename", handleRolelimitsQuery)

	//请求/user/queryall?skip=0&limit=10
	// s.HandleFunc("/queryall", handlePartAll)
}
func initRoleApi(r *mux.Router) {
	s := r.PathPrefix("/role").Subrouter()
	// s.HandleFunc("/list", UserListHandler)
	s.HandleFunc("/updsave", handleSaveRole)
	//请求/rolelimits/querybyrolename?rolename=xxx
	s.HandleFunc("/query", handleRoleQuery)

}
func initDepartmentApi(r *mux.Router) {
	s := r.PathPrefix("/depart").Subrouter()
	// s.HandleFunc("/list", UserListHandler)
	s.HandleFunc("/updsave", handleSaveDepart)
	//请求/rolelimits/querybyrolename?rolename=xxx
	s.HandleFunc("/query", handleDepartQuery)
}

func (roleMgr *RoleMgr) QueryAllDepart() (departs []*common.Department, err error) {

	var (
		cursor *mongo.Cursor
		ctx    context.Context
		depart *common.Department
	)
	if cursor, err = roleMgr.departCollection.Find(ctx, bson.M{}); err != nil {
		return
	}
	defer cursor.Close(ctx)

	//反序列化到bson
	for cursor.Next(ctx) {
		depart = &common.Department{}
		if err = cursor.Decode(depart); err != nil {
			continue
		}
		// fmt.Println(jobLog)
		departs = append(departs, depart)
	}
	return
}

func (roleMgr *RoleMgr) QueryAllRole() (roles []*common.Role, err error) {

	var (
		cursor *mongo.Cursor
		ctx    context.Context
		role   *common.Role
	)
	if cursor, err = roleMgr.roleCollection.Find(ctx, bson.M{}); err != nil {
		return
	}
	defer cursor.Close(ctx)

	//反序列化到bson
	for cursor.Next(ctx) {
		role = &common.Role{}
		if err = cursor.Decode(role); err != nil {
			continue
		}
		// fmt.Println(jobLog)
		roles = append(roles, role)
	}
	return
}

func handleRoleQuery(resp http.ResponseWriter, req *http.Request) {
	var (
		err   error
		bytes []byte
		roles []*common.Role
		// rolelimit     *common.RoleLimits
	)

	if roles, err = G_roleMgr.QueryAllRole(); err != nil {
		goto ERR
	}
	if bytes, err = common.BuildResponse(0, "success", roles); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleDepartQuery(resp http.ResponseWriter, req *http.Request) {
	var (
		err     error
		bytes   []byte
		departs []*common.Department
		// rolelimit     *common.RoleLimits
	)

	if departs, err = G_roleMgr.QueryAllDepart(); err != nil {
		goto ERR
	}
	if bytes, err = common.BuildResponse(0, "success", departs); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func (roleMgr *RoleMgr) handleSaveRole(role *common.Role) (err error) {

	var (
		doccount int64
	)
	role.CreateTime = common.BuildTimeNowStr()
	doccount, err = roleMgr.roleCollection.CountDocuments(context.TODO(), bson.M{"roleName": role.RoleName})
	if doccount > 0 {
		_, err = roleMgr.roleCollection.UpdateOne(context.TODO(), bson.M{"roleName": role.RoleName}, bson.M{"$set": role})
	} else {
		roleMgr.roleCollection.InsertOne(context.TODO(), role)
	}

	return
}

func (roleMgr *RoleMgr) handleSaveDepart(depart *common.Department) (err error) {

	var (
		doccount int64
	)
	depart.CreateTime = common.BuildTimeNowStr()
	doccount, err = roleMgr.departCollection.CountDocuments(context.TODO(), bson.M{"departName": depart.DepartName})
	if doccount > 0 {
		_, err = roleMgr.departCollection.UpdateOne(context.TODO(), bson.M{"departName": depart.DepartName}, bson.M{"$set": depart})
	} else {
		roleMgr.departCollection.InsertOne(context.TODO(), depart)
	}

	return
}

func handleSaveRole(resp http.ResponseWriter, req *http.Request) {
	var (
		err         error
		bytes       []byte
		role        *common.Role
		roleinfostr string
		// rolelimit     *common.RoleLimits
	)
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	roleinfostr = req.PostForm.Get("roleinfo")

	if err = json.Unmarshal([]byte(roleinfostr), &role); err != nil {
		goto ERR
	}
	if err = G_roleMgr.handleSaveRole(role); err != nil {
		goto ERR
	}
	if bytes, err = common.BuildResponse(0, "success", "新增角色成功"); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleSaveDepart(resp http.ResponseWriter, req *http.Request) {
	var (
		err           error
		bytes         []byte
		depart        *common.Department
		departinfostr string
		// rolelimit     *common.RoleLimits
	)
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	departinfostr = req.PostForm.Get("departinfo")

	if err = json.Unmarshal([]byte(departinfostr), &depart); err != nil {
		goto ERR
	}
	if err = G_roleMgr.handleSaveDepart(depart); err != nil {
		goto ERR
	}
	if bytes, err = common.BuildResponse(0, "success", "新增部门成功"); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

// rolelimits:{"rolename":"会计","data":[{"rolename":"会计","partname":"线索","partopt":"线索管理-删除"},{"rolename":"会计","partname":"线索","partopt":"线索管理-新增"},{"rolename":"会计","partname":"线索","partopt":"线索管理-详情"}]}
func handleOpdSaveRoleInfo(resp http.ResponseWriter, req *http.Request) {
	var (
		err           error
		bytes         []byte
		res           *simplejson.Json
		rolelimitsstr string
		rows          []interface{}
		rolelimit     *common.RoleLimits
		rolename      string
		// rolelimit     *common.RoleLimits
	)

	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	rolelimitsstr = req.PostForm.Get("rolelimits")

	// fmt.Println(rolelimitsstr)

	res, err = simplejson.NewJson([]byte(rolelimitsstr))
	rolename, err = res.Get("rolename").String()
	rows, err = res.Get("data").Array()

	G_roleMgr.deleteRoleLimitsInfo(rolename)

	for _, row := range rows {
		rowstr, _ := json.Marshal(row)
		json.Unmarshal(rowstr, &rolelimit)
		G_roleMgr.updSaveRoleLimitsInfo(rolelimit)
	}

	if bytes, err = common.BuildResponse(0, "success", "权限设置完成"); err == nil {
		resp.Write(bytes)
	}

	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleRolelimitsQuery(resp http.ResponseWriter, req *http.Request) {
	var (
		err         error
		bytes       []byte
		roleinfoarr []*common.RoleLimits
	)

	query := req.URL.Query()
	rolename := query.Get("rolename")
	// fmt.Println(rolename)

	if roleinfoarr, err = G_roleMgr.queryRoleLimitsInfo(rolename); err != nil {
		goto ERR
	} else {
		if bytes, err = common.BuildResponse(0, "success", roleinfoarr); err == nil {
			resp.Write(bytes)
		}
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func InitRoleMgr() (err error) {
	
	G_roleMgr = &RoleMgr{
		client:               G_MongoMgr.client,
		roleLimitsCollection: G_MongoMgr.MongdbConnect.Collection("rolelimit"),
		roleCollection:       G_MongoMgr.MongdbConnect.Collection("role"),
		departCollection:     G_MongoMgr.MongdbConnect.Collection("department"),
	}

	return
}
